iT邦幫忙

2025 iThome 鐵人賽

DAY 28
0
AI & Data

進擊的 n8n系列 第 28

Day 28:n8n 自動化實戰 - 串接 Google Calendar API,每日自動提醒今日行程

  • 分享至 

  • xImage
  •  

我們在前一天有大致串接了被動接收通知 (Webhook) 和定時執行任務 (Schedule)。

今天就來試試看跟分享自動化中最核心的技能:n8n 如何主動串接外部 API (Application Programming Interface)。API 是應用程式之間溝通的橋樑,讓我們可以讀取或寫入其他服務的資料。

我們將挑戰並實作看看一個個人助理情境:「每天早上,自動抓取我 Google Calendar 上今天的行程,並透過 Email 發送一則提醒給我。」

這個流程將會結合前一天跟各位分享到的 n8n 排程觸發,以及全新的 API 串接技巧。

什麼是 API 串接?

想像一下你去餐廳點餐:

  • 你 (客戶):想要一道宮保雞丁。
  • 菜單 (API 文件):告訴你有哪些菜可以點,以及要怎麼點。
  • 服務生 (API):接收你的點餐需求,去廚房溝通,然後把菜送回來給你。
  • 廚房 (後端服務):真正處理餐點的地方。

在 n8n 中,我們就是「客戶」,透過 HTTP Request 節點或各種應用程式專屬的節點 (如 Google Calendar 節點),向外部服務 (如 Google) 的「服務生 (API)」發出請求,取得我們想要的資料或服務。

範例實作流程

  1. 每天早上 8 點觸發 (使用 Schedule 節點)。
  2. 連接到 Google Calendar,並取得今天的所有活動 (使用 Google Calendar 節點)。
  3. 格式化行程資訊,組合成一則易讀的提醒訊息 (使用 Set 節點)。
  4. 將提醒訊息透過 Email 寄出 (使用 Send Email 節點)。

步驟 1:設定排程觸發器

這部分和昨天一樣,我們建立一個 Schedule 節點,並設定它在每天早上 8 點於 Asia/Taipei 時區執行(以上時間點為範例)。

步驟 2:串接 Google Calendar

這是今天的重頭戲。n8n 已經內建了 Google Calendar 節點,大大簡化了 API 串接的複雜度。

  1. Schedule 節點後方新增 Google Calendar 節點。
  2. Credential: 第一次使用,你需要授權 n8n 存取你的 Google Calendar。點擊 Create New,登入你的 Google 帳號,並同意授權(簡單說就是到 Google Cloud Console 建立 OAuth 2.0 憑證;記得要連接你個人的 Gmail 帳號)。如下圖(就一路根據 Google Cloud 的指示點選到最後吧!XD):

pic1

pic2

補充:其中有一步是要將 n8n 頁面上的 OAuth Redirect URL 貼回到剛剛 Google Cloud 頁面上的

pic2

pic2

然後你就會獲得你的 Client ID 跟 Client Secret!你也可以將 OAuth client 的 JSON 下載下來囉!下一步就是 create Google Calendar 的 Credential,如以下兩個圖示(記得從 GCP Clients 頁面上複製你的 Client Secret):

pic2

pic2

串接成功後,就會跳出以下畫面(記得先點選上一個圖示中的 Sign with Google):

pic2

再來以下就是 n8n 的設定了:
3. Resource: 選擇 Event (活動)。
4. Operation: 選擇 Get Many (取得多個)。
5. Calendar: 選擇你要讀取的日曆 (通常是你的主要日曆)。
6. Return All: 保持勾選,以取得所有符合條件的行程。
7. Options -> Add Option: 這裡要設定篩選條件,我們只想要「今天」的行程。

  • Time Min: 設定為 {{ new Date().setHours(0, 0, 0, 0) }}。這是一個 JavaScript 表達式,代表今天的凌晨 0 點。
  • Time Max: 設定為 {{ new Date().setHours(23, 59, 59, 999) }}。代表今天的午夜 23:59。

以上五個步驟可以從以下 n8n 實際畫面找到相對應的參數:

pic2

  1. 點擊 Execute Node 測試一下。如果你的行事曆今天有安排活動,你應該能在右邊的輸出結果中看到行程的詳細資料 (JSON 格式)。如下圖:

pic2

pic2

步驟 3:格式化行程內容

從 API 拿回來的原始資料是一堆 JSON,直接寄出去很難閱讀。我們需要用 Set 節點或 Code 節點來整理它。這裡我們用 Set 節點搭配表達式,做一個簡單的格式化。

  1. Google Calendar 節點後方新增 Set 節點。
    我們希望產出的格式像這樣:
  • 09:00~10:00:團隊會議
  • 14:00~15:30:客戶 Demo
  1. Set 節點中,新增一個名為 scheduleText 的 Value。
  2. 在 Value 欄位,我們要用一點 JavaScript 來處理陣列資料:
{{  
  $input.all().map(item \=\> {  
    const start \= new Date(item.json.start.dateTime).toLocaleTimeString('zh-TW', { hour: '2-digit', minute: '2-digit' });  
    const end \= new Date(item.json.end.dateTime).toLocaleTimeString('zh-TW', { hour: '2-digit', minute: '2-digit' });  
    return \`- ${start}\~${end}:${item.json.summary}\`;  
  }).join('\\\\\\\\n')  
}}

這段程式碼的意思是:

  • $input.all(): 取得從 Google Calendar 節點傳來的所有行程項目。
  • .map(...): 針對每一個行程項目,進行處理。
  • new Date(...): 將 ISO 格式的時間字串轉換成日期物件。
  • .toLocaleTimeString(...): 將時間格式化為 HH:mm 的格式。
  • item.json.summary: 取得行程的標題。
  • .join('\\n'): 將處理完的所有行程字串,用換行符號組合起來。

步驟 4:寄送提醒 Email

這一步和昨天完全一樣。

  1. Set 節點後方新增 Send Email 節點。
  2. To: 填寫你自己的 Email。
  3. Subject: 今日行程提醒 ({{ new Date().toLocaleDateString('zh-TW') }})
  4. HTML: 勾選。
  5. Text: 內容設為 {{ $json.scheduleText }},並可以在前面加上一些問候語。
Hi,

這是您今天的行程:

{{ $json.scheduleText }}

祝您有充實的一天!

處理「沒有行程」的狀況 (IF 節點)

如果今天沒有任何行程,Google Calendar 節點會回傳空陣列,Set 節點也會產生空的 scheduleText。我們可能不希望在沒有行程的日子還收到一封空信。這時 IF 節點就派上用場了。

  1. Google CalendarSet 節點之間,插入一個 IF 節點。
  2. Condition: 設定一個條件,檢查從 Google Calendar 拿回來的資料是否為空。
    • Value 1: {{ $items().length }} (代表傳入節點的項目數量)
    • Operation: Larger Than
    • Value 2: 0
  3. 這樣一來,只有當 Google Calendar 節點有回傳資料時 (長度大於 0),true 分支後面的 SetSend Email 節點才會被執行。

結語

今天,我們成功地打造了一個實用的個人助理!這個範例展示了 n8n 的核心價值:串連不同的服務,並在中間加入邏輯處理,完成一個有意義的自動化任務。

API 串接是自動化的靈魂。學會了這個技巧,你就可以:

  • 串接 Slack API,自動發送訊息到指定頻道。
  • 串接 OpenAI API,打造自己的 AI 客服。
  • 串接電商平台的 API,自動同步訂單資訊。

明天,我們將把前幾天的技能整合起來,完成一個更複雜的 跨平台整合 專案!


上一篇
Day 27:n8n 自動化實戰 - 用排程觸發器,每日早上九點自動寄送 Email 報表
下一篇
Day 29:n8n 自動化實戰 - 跨平台整合,實現「表單提交→存入 Google Sheet→寄送 Email 通知」的完整流程
系列文
進擊的 n8n29
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言